<!-- 
    ==0.watchEffect监听
        =触发时机
            响应式数据改变，触发
        =立即执行
        =自动收集
        watchEffect(()=>{})
    ==1.跨组件传值的多种方式
        1.ref
        2.父传子
        3.子传父
        4.v-model
        5.插槽

    ==2.ref获取真实Dom 或者组件实例
        1.导入ref
        2.标签属性ref="div"
        3.声明const div=ref(null)
            查看
        onMounted(()=>{
             log(div)
        })

    ==3.组合式 父传子
        0.父子组件
        1.自定义属性
        2.全局definedProps
         方法1：template直接接收
            const props=defineProps([''])
         方法2：变量接收
            const props = defineProps(["data","fn"]);
         方式3：显示声明
            const props = defineProps({
                data: {
                    type: String,
                    default: "123",
                },
            });
    ==4.子传父
            1.父组件定义接收方法
              const fn = (val) => { console.log(val)};
            2.往子组件传方法
               <Ex4 @childFn="fn" /> 
            3.定义自定义事件
                defineEmits(["childFn"]);
            4.触发自定义事件
                @click="$emit('childFn', '子组件')"
    ==5.选项式父传子
            1.emits: ["example"],
            2.props接受父组件数据
              setup(props, { emit }) {
                3.解构emit 
                 @click=emit("example", 123, 456);
                return {
                     ff,
                };
            }

    ==6.v-model
            1.父子组件
            2.v-model 绑定组件
                let val=ref()
                <child v-model="val" />
                    分解：
                        @input
                        :value
            3.defin
                 modelValue
                 @update:modelValue
                 defineProps(['modelValue'])
            const emit=defineEmits(['update:modelValue'])
            :value="(['modelValue'])"
            @input="emit('update:modelValue',$event.target.value)"

    ==7.跨组件
        vue.js devtools
        1.导入{provide}
            provide(message,"abc")
        2.导入{inject}
            const message=inject('message')
    
    ==7.symbol唯一值
        1.全局common/key.js
            export const key1 = Symbol();
        2.provide(key,'值')
        3.log(inject(key))

    ==8.插槽
        封装组件的时候可以向组件传入结构
          1.子组件slot
          2.父组件引入，组件内传入结构

        =具名
         1.slot name属性
         2.template slot占位

        =作用域插槽
         1.slot :自定义属性='传值'
         2.template v-slot:name属性="{属性}"
    ==9.自定义指令
        全局app.directive('test',{
            mounted(el,binding){
            binding.value
            el.style.display
                 }
            updated(el,binding){
                }
            })
        2.使用
             v-test
        3.外链
            directives/index.js
    ==9.局部指令
            const vHide = {
                mounted(){}
                updated(){}
            }
    ==10.telport(是把一个组件 渲染到一个指定的 结构里面)
        1.包裹组件（to属性值为 渲染的节点位置）
           <Teleport to="#app">
                <Ex14 :show="show" />
           </Teleport>    

    ==11.路由
        0.下载
             yarn add vue-router
        1.新建router/index.js
             导入{createRouter,createWebHashHistory} vue-router
        2.
         进行路由表的配置
            const routes=[
            {
                path:''
                component:()=>import('')
             }
            ]
        1.创建路由对象
            const router=createRouter({
                routes,
             3. 指定路由模式
                history:createWebHashHistory()
            })

        2.app.vue 路由出口
            <router-view>
        3.main.js 注册路由
            const app=createApp(App)
            app.use(router);
        二级路由
            <router-view>

        ==路由跳转
            1.路由hook
                useRouter
            2.路由实例
                router=useRouter()
            3.路由跳转
                router.push

        ==路由params参数
            1.路由params传参
                 path: "/detail/:id"
            2.路由实例
                useRoute
            3.获取参数
                route=useRoute().params

        ==.query传参

 -->
